package com.campsys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campsys.entity.*;
import com.campsys.mapper.CampClassMapper;
import com.campsys.mapper.CampClassStudentMapper;
import com.campsys.mapper.CampClassTeacherMapper;
import com.campsys.mapper.ActivityMapper;
import com.campsys.mapper.UserMapper;
import com.campsys.service.CampClassService;
import com.campsys.service.dto.CampClassDTO;
import com.campsys.service.dto.CampClassQueryDTO;
import com.campsys.service.dto.TeacherAssignDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class CampClassServiceImpl implements CampClassService {
    
    @Autowired
    private CampClassMapper classMapper;
    
    @Autowired
    private CampClassTeacherMapper teacherMapper;
    
    @Autowired
    private CampClassStudentMapper studentMapper;
    
    @Autowired
    private ActivityMapper activityMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public IPage<CampClass> getClassList(Page<CampClass> page, CampClassQueryDTO queryDTO) {
        return classMapper.selectClassList(page, queryDTO);
    }
    
    @Override
    @Transactional
    public void addClass(CampClassDTO classDTO) {
        // 验证活动是否存在且有效
        Activity activity = activityMapper.selectById(classDTO.getActivityId());
        if (activity == null) {
            throw new IllegalArgumentException("活动不存在，ID: " + classDTO.getActivityId());
        }
        if (activity.getStatus() != 1) {
            throw new IllegalArgumentException("活动已关闭，无法添加教学班");
        }
        
        // 验证教师列表不为空
        if (classDTO.getTeachers() == null || classDTO.getTeachers().isEmpty()) {
            throw new IllegalArgumentException("教师列表不能为空");
        }
        
        // 验证教师是否存在且是教师角色
        for (TeacherAssignDTO teacher : classDTO.getTeachers()) {
            User user = userMapper.selectById(teacher.getTeacherId());
            if (user == null) {
                throw new IllegalArgumentException("教师不存在，ID: " + teacher.getTeacherId());
            }
            if (user.getRoleType() != 2) {  // 2-教师角色
                throw new IllegalArgumentException("用户不是教师角色，ID: " + teacher.getTeacherId() + 
                    ", 角色类型: " + user.getRoleType());
            }
            if (user.getStatus() != 1) {
                throw new IllegalArgumentException("教师账号已禁用，ID: " + teacher.getTeacherId());
            }
            if (teacher.getRoleType() != 1 && teacher.getRoleType() != 2) {
                throw new IllegalArgumentException("无效的教师角色类型: " + teacher.getRoleType() + 
                    "，只能是1(主讲)或2(助教)");
            }
        }
        
        // 添加班级基本信息
        CampClass campClass = new CampClass();
        BeanUtils.copyProperties(classDTO, campClass);
        campClass.setStatus(1);
        campClass.setCurrentStudents(0);
        campClass.setCreateTime(LocalDateTime.now());
        campClass.setCreateBy("admin");  // TODO: 从当前登录用户获取
        classMapper.insert(campClass);
        
        // 添加教师关系
        try {
            assignTeachers(campClass.getId(), classDTO.getTeachers());
        } catch (Exception e) {
            log.error("添加教师关系失败", e);
            throw new RuntimeException("添加教师关系失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public void updateClass(CampClassDTO classDTO) {
        // 更新班级基本信息
        CampClass campClass = new CampClass();
        BeanUtils.copyProperties(classDTO, campClass);
        campClass.setUpdateTime(LocalDateTime.now());
        campClass.setUpdateBy("admin");  // TODO: 从当前登录用户获取
        classMapper.updateById(campClass);
        
        // 更新教师关系
        LambdaQueryWrapper<CampClassTeacher> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CampClassTeacher::getClassId, classDTO.getId());
        teacherMapper.delete(wrapper);
        assignTeachers(classDTO.getId(), classDTO.getTeachers());
    }
    
    @Override
    @Transactional
    public void deleteClass(Long id) {
        // 删除教师关系
        LambdaQueryWrapper<CampClassTeacher> teacherWrapper = new LambdaQueryWrapper<>();
        teacherWrapper.eq(CampClassTeacher::getClassId, id);
        teacherMapper.delete(teacherWrapper);
        
        // 删除学员关系
        LambdaQueryWrapper<CampClassStudent> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(CampClassStudent::getClassId, id);
        studentMapper.delete(studentWrapper);
        
        // 删除班级
        classMapper.deleteById(id);
    }
    
    @Override
    public void updateStatus(Long id, Integer status) {
        CampClass campClass = new CampClass();
        campClass.setId(id);
        campClass.setStatus(status);
        campClass.setUpdateTime(LocalDateTime.now());
        campClass.setUpdateBy("admin");  // TODO: 从当前登录用户获取
        classMapper.updateById(campClass);
    }
    
    @Override
    @Transactional
    public void importStudents(Long classId, List<Long> studentIds) {
        // 获取班级信息
        CampClass campClass = classMapper.selectById(classId);
        if (campClass == null) {
            throw new IllegalArgumentException("班级不存在");
        }
        
        // 验证班级状态
        if (campClass.getStatus() != 1) {
            throw new IllegalArgumentException("班级已关闭，无法导入学员");
        }
        
        // 处理当前学生数为null的情况
        int currentStudents = campClass.getCurrentStudents() == null ? 0 : campClass.getCurrentStudents();
        
        // 验证是否超过最大人数
        if (currentStudents + studentIds.size() > campClass.getMaxStudents()) {
            throw new IllegalArgumentException("导入后将超过班级最大人数限制：" + campClass.getMaxStudents());
        }
        
        // 检查学生是否已在班级中
        for (Long studentId : studentIds) {
            // 验证学生是否存在且状态正常
            User student = userMapper.selectById(studentId);
            if (student == null) {
                throw new IllegalArgumentException("学生不存在，ID: " + studentId);
            }
            if (student.getRoleType() != 3) {  // 3-学生角色
                throw new IllegalArgumentException("用户不是学生角色，ID: " + studentId);
            }
            if (student.getStatus() != 1) {
                throw new IllegalArgumentException("学生账号已禁用，ID: " + studentId);
            }
            
            // 检查是否已在班级中
            LambdaQueryWrapper<CampClassStudent> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CampClassStudent::getClassId, classId)
                    .eq(CampClassStudent::getStudentId, studentId)
                    .eq(CampClassStudent::getStatus, 1);  // 只检查状态正常的记录
            
            if (studentMapper.selectCount(wrapper) > 0) {
                throw new IllegalArgumentException("学生已在班级中，学生ID: " + studentId);
            }
        }
        
        // 导入学生
        for (Long studentId : studentIds) {
            try {
                CampClassStudent student = new CampClassStudent();
                student.setClassId(classId);
                student.setStudentId(studentId);
                student.setJoinTime(LocalDateTime.now());
                student.setStatus(1);
                studentMapper.insert(student);
            } catch (Exception e) {
                log.error("导入学生失败: classId={}, studentId={}", classId, studentId, e);
                throw new RuntimeException("导入学生失败，学生ID: " + studentId);
            }
        }
        
        // 更新班级当前学生数量
        campClass.setCurrentStudents(currentStudents + studentIds.size());
        campClass.setUpdateTime(LocalDateTime.now());
        campClass.setUpdateBy("admin");  // TODO: 从当前登录用户获取
        classMapper.updateById(campClass);
    }
    
    @Override
    public IPage<User> getClassStudents(Page<User> page, Long classId) {
        return classMapper.selectClassStudents(page, classId);
    }
    
    @Override
    @Transactional
    public void removeStudent(Long classId, Long studentId) {
        LambdaQueryWrapper<CampClassStudent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CampClassStudent::getClassId, classId)
                .eq(CampClassStudent::getStudentId, studentId);
        studentMapper.delete(wrapper);
        
        // 更新班级当前学生数量
        CampClass campClass = classMapper.selectById(classId);
        campClass.setCurrentStudents(campClass.getCurrentStudents() - 1);
        classMapper.updateById(campClass);
    }
    
    private void assignTeachers(Long classId, List<TeacherAssignDTO> teachers) {
        for (TeacherAssignDTO teacher : teachers) {
            try {
                CampClassTeacher classTeacher = new CampClassTeacher();
                classTeacher.setClassId(classId);
                classTeacher.setTeacherId(teacher.getTeacherId());
                classTeacher.setRoleType(teacher.getRoleType());
                classTeacher.setAssignTime(LocalDateTime.now());
                classTeacher.setStatus(1);
                teacherMapper.insert(classTeacher);
            } catch (Exception e) {
                log.error("添加教师关系失败: classId={}, teacherId={}", classId, teacher.getTeacherId(), e);
                throw new RuntimeException("添加教师关系失败，教师ID: " + teacher.getTeacherId());
            }
        }
    }
} 